package com.ruoyi.common.utils;import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class RSAUtils {

    // 生成RSA密钥对
    public static KeyPair generateKeyPair(int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(keySize);
        return keyPairGenerator.generateKeyPair();
    }

    // 获取Base64编码的公钥字符串
    public static String getPublicKeyToBase64(PublicKey publicKey) {
        return Base64.getEncoder().encodeToString(publicKey.getEncoded());
    }

    // 获取Base64编码的私钥字符串
    public static String getPrivateKeyToBase64(PrivateKey privateKey) {
        return Base64.getEncoder().encodeToString(privateKey.getEncoded());
    }

    // 将公钥转换为PEM格式
    public static String getPublicKeyToPEM(PublicKey publicKey) {
        return "-----BEGIN PUBLIC KEY-----\n" +
                chunkString(Base64.getEncoder().encodeToString(publicKey.getEncoded()), 64) +
                "\n-----END PUBLIC KEY-----";
    }

    // 将私钥转换为PEM格式（PKCS8）
    public static String getPrivateKeyToPEM(PrivateKey privateKey) {
        return "-----BEGIN PRIVATE KEY-----\n" +
                chunkString(Base64.getEncoder().encodeToString(privateKey.getEncoded()), 64) +
                "\n-----END PRIVATE KEY-----";
    }


    // 从Base64字符串恢复公钥
    public static PublicKey getPublicKeyFromBase64(String base64PublicKey) throws Exception {
        byte[] decoded = Base64.getDecoder().decode(base64PublicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }

    // 从Base64字符串恢复私钥（PKCS8）
    public static PrivateKey getPrivateKeyFromBase64(String base64PrivateKey) throws Exception {
        byte[] decoded = Base64.getDecoder().decode(base64PrivateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    // 从PEM格式恢复公钥
    public static PublicKey getPublicKeyFromPEM(String pemPublicKey) throws Exception {
        String publicKeyPEM = pemPublicKey
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "")
                .replaceAll("\\s", "");
        return getPublicKeyFromBase64(publicKeyPEM);
    }

    // 从PEM格式恢复私钥（PKCS8）
    public static PrivateKey getPrivateKeyFromPEM(String pemPrivateKey) throws Exception {
        String privateKeyPEM = pemPrivateKey
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s", "");
        return getPrivateKeyFromBase64(privateKeyPEM);
    }

    // RSA加密
    public static String encrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    // RSA解密
    public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }

    // 格式化长字符串（每64字符加换行）
    private static String chunkString(String str, int chunkSize) {
        return str.replaceAll("(.{"+chunkSize+"})", "$1\n");
    }

    public static void main(String[] args) {
        try {
            // 1. 生成密钥对
            KeyPair keyPair = generateKeyPair(2048);
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();

            // 2. 加密示例
            String originalText = "Hello, RSA加密测试!";
            String encryptedText = encrypt(originalText, publicKey);
            System.out.println("加密后: " + encryptedText);

            // 3. 解密示例
            String decryptedText = decrypt(encryptedText, privateKey);
            System.out.println("解密后: " + decryptedText);

            // 4. Base64密钥转换测试
            String publicKeyBase64 = getPublicKeyToBase64(publicKey);
            String privateKeyBase64 = getPrivateKeyToBase64(privateKey);
            System.out.println("\n公钥(Base64):\n" + publicKeyBase64);
            System.out.println("\n私钥(Base64):\n" + privateKeyBase64);

            PublicKey restoredPublicKey = getPublicKeyFromBase64(publicKeyBase64);
            PrivateKey restoredPrivateKey = getPrivateKeyFromBase64(privateKeyBase64);

            // 使用恢复的密钥测试
            String testEncrypted = encrypt("测试恢复的密钥", restoredPublicKey);
            System.out.println("\n使用恢复公钥加密: " + testEncrypted);
            System.out.println("使用恢复私钥解密: " + decrypt(testEncrypted, restoredPrivateKey));

            /*String publicKey1 = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n" +
            "nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=";*/
            String publicKey1 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp/Giv5v8Ip/M5CrzVQ+25uP8cWiSlekJqAx/l7rbvdr3EOlEs9EYUwLiLqGokSbCbMO5DhO1xzEsJ7K6H8LXyR38x1zWuQ/ElfL6ooRKIeI9N4WWteGKdA1LSUNjoOBmxYXWAQUy9P01CnaGCz7t44LzRAtm394/LovhU7Sn5+pEFngPloLiw4rroDFj/qsQ/qJ+ZNfO1dDSlU4mD50xoATp6ir+Z/m5tHGGHZD+AwAxAepZib+cAuFbDOZBCR0iVjn/+fkroj/7D19ex3iX7R2KUUQsNyq68dzOJRhQ57sAlq4UQ7k/gsYrrRIn/qm/ZO+ZkFKmsCq400vSuU2ekQIDAQAB";

            String privateKey1 = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n" +
                    "7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n" +
                    "PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n" +
                    "kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n" +
                    "cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n" +
                    "DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n" +
                    "YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n" +
                    "UP8iWi1Qw0Y=";
            privateKey1="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCn8aK/m/win8zkKvNVD7bm4/xxaJKV6QmoDH+Xutu92vcQ6USz0RhTAuIuoaiRJsJsw7kOE7XHMSwnsrofwtfJHfzHXNa5D8SV8vqihEoh4j03hZa14Yp0DUtJQ2Og4GbFhdYBBTL0/TUKdoYLPu3jgvNEC2bf3j8ui+FTtKfn6kQWeA+WguLDiuugMWP+qxD+on5k187V0NKVTiYPnTGgBOnqKv5n+bm0cYYdkP4DADEB6lmJv5wC4VsM5kEJHSJWOf/5+SuiP/sPX17HeJftHYpRRCw3Krrx3M4lGFDnuwCWrhRDuT+CxiutEif+qb9k75mQUqawKrjTS9K5TZ6RAgMBAAECggEAH4RmYYUZdTn+DpfM4Jq5XW1Ns87HK6D3MfVegJANqvyLvz23qfNEmFeDMPMfmlXmyNiWQwEJ7R7aRXzyFwHO0yxwgs12cnZ2ExntVVB0RRWbHW9RkEKKZCsWhOJDsS5LuyfZuIlMPdPC/3qsvzGJHVg25P8qyDqCKu8PU1Ek7Y2n+bvS2SDLkHCUMVRKUnT1I3vYFeKlWFuzbzE9ZS2iJ/VJRAlQb7gKuQtyVEHzN/dTGz8CIaAKmR4k1k7ccvocJfILXFPqx4IsOD2gdhNOAcoX0FjMFyhJwhNFxajeXoUZ7wm7jsx8lyBb2QfoxLJI/NLqERGnPVgLkGwdSI62zQKBgQDnpO9h8jVgYNCurERrtrOeSRkirLkVSoO0mnj8uhJO7dUPrecUy/ojGgZcSYjSdq7qdqa0IkGZzdtlhUyMrbezrp1fRBFlx8ypQHhmFy+gd9LHcEa3lkzU12NAFiByOF760r4juCOXcp64GaivdSS/C/0tjlpraI7eTKuuTxjRBwKBgQC5mhseUBK21XSEOWp4DAkGLA5KOD12mp6xuYsx0V5bHhoYsZCa2InUkRcQcMLDlJcmJPp5fi043PuC1M70HaXvNIX5mjdNuQs7HJCouYgYjTS/X3KMy5IX7R5zwAaLKxfS+YAcVAzQA7qR/7HzqhKW6zFuJuaYV6FUbYebm07lpwKBgGjbLkkl/Kdt68jFzgr8Hv6NlEUv7nAG1OuR6SZtjBASdJmuXKX7V3VAOJTZ7IdolfEoWHm97/gRSTkBSA9+K2O4rSAMjduGv8v1lQqRgEuhMdZ5qmk8LfdCsHi4C2PoxIXBk7RTjDjn95TaeJND8ahRYv+WKrPoFpPmHOjAgTlNAoGBAIoVYxOcUy//gt5UsSd7HMOgx0jkqqWwx1xGRI7dy6tSq+uvP3xUmcax40zx95T22bUhUdBN1Ws2zVA673WjES70DrDy0S5b+0URLXa6AczyUUoHwvuJALoYSc2oEbY8a08lHPD2f0nLXGT+rPAxmf76IB5phqnUmExt6LQWSg6FAoGAKAa5IjO9V0pRczTyLKltaSmlS/iaL/Vm37YyFUXBNqw6rebtGrKESP9qsoh5n+6WhKZ0IMVv2+RWsZ8GzHOXo29dMy/9RMWjQInNLm19LRQ69Tn8YMwf4ZUYi6oB7Ne5jxBb7Dpe3slp27drw3pNzMEYWtUU5FxDG4KSroUmaWA=";
            PublicKey restoredPublicKey1 = getPublicKeyFromBase64(publicKey1);
            PrivateKey restoredPrivateKey1 = getPrivateKeyFromBase64(privateKey1);


            // 2. 加密示例
            String originalText1 = "Hello, RSA加密测试!";//!!!!发射点发射点发生!
            String encryptedText1 = encrypt(originalText1, restoredPublicKey1);
            System.out.println("加密后: " + encryptedText1);

            // 3. 解密示例
            String decryptedText1 = decrypt(encryptedText1, restoredPrivateKey1);
            System.out.println("解密后: " + decryptedText1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}